#coding:utf-8
from . import api
from flask import request, current_app, jsonify, session
from ihome import redis_store,db
from ihome.utils.constains import LOGIN_ERROR_MAX_TIME, LOGIN_INTERVAL
import re
from ihome.utils.response_code import RET
from ihome.models import User
from sqlalchemy.exc import IntegrityError


@api.route('/user', methods=['POST'])
def register():
    req_dict = request.get_json()
    mobile = req_dict.get('mobile')
    sms_code = req_dict.get('sms_code')
    password = req_dict.get('password')
    password2 = req_dict.get('password2')

    if not all([mobile, sms_code, password]):
        return jsonify(errno=RET.PARAMERR, errmsg="数据不完整")

    # 判断手机格式
    if not re.match(r"1[34578]\d{9}", mobile):
        return jsonify(errno=RET.PARAMERR, errmsg="手机格式不正确")
    # 判断密码是否一致
    if password != password2:
        return jsonify(errno=RET.PARAMERR, errmsg="密码不一致")

    try:
        real_sms_code = redis_store.get("sms_code_%s" % mobile)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="校验短信失败")
    # 判断短信验证码是否过期
    if real_sms_code is None:
        return jsonify(errno=RET.NODATA, errmsg="短信过期")
    # 删除短信码防止重复验证
    try:
        redis_store.delete("sms_code_%s" % mobile)
    except Exception as e:
        current_app.logger.error(e)

    # 校验短信
    if real_sms_code != sms_code:
        return jsonify(errno=RET.NODATA, errmsg="短信校验失败")


    # 判断手机号码是否已经被注册
    try:
        user = User.query.filter_by(mobile=mobile).first()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="数据库异常")
    else:
        if user is not None:
            # 该号码已存在
            return jsonify(errno=RET.DATAEXIST, errmsg="用户号码已注册")


    # 保存到数据库

    user = User(name=mobile, mobile=mobile)
    user.password = password

    try:
        db.session.add(user)
        db.session.commit()
        db.session.rollback()
    except IntegrityError as e:
        db.session.rollback()
        current_app.logger.error(e)
        return jsonify(errno=RET.DATAEXIST, errmsg="手机号码已存在")
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="数据库异常")

    session['name'] = mobile
    session['mobile'] = mobile
    session['user_id'] = user.id

    return jsonify(errno=RET.OK, errmsg="保存成功")


# 登录
@api.route('/session', methods=["POST"])
def login():
    req_data = request.get_json()

    mobile = req_data.get('mobile')
    password = req_data.get('password')

    if not all([mobile, password]):
        return jsonify(errno=RET.PARAMERR, errmsg="参数不完整")

    if not re.match(r'1[34578]\d{9}', mobile):
        return jsonify(errno=RET.PARAMERR, errmsg="号码格式不正确")

        # 判断错误次数是否超过一定次数，如果是，则返回
    user_ip = request.remote_addr
    try:
        user_access_num = redis_store.get("access_num_%s" % user_ip)
    except Exception as e:
        current_app.logger.error(e)
    else:
        if user_access_num is not None and int(user_access_num) >= LOGIN_ERROR_MAX_TIME:
            return jsonify(errno=RET.REQERR, errmsg="请求错误次数过多，请稍后再试")

    try:
        user = User.query.filter_by(mobile=mobile).first()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="获取用户信息失败")

    if user is None or user.check_password(password) is False:
        try:
            redis_store.incr("access_num_%s" % user_ip)
            redis_store.expire("access_num_%s" % user_ip, LOGIN_INTERVAL)
        except Exception as e:
            current_app.logger.error(e)
        return jsonify(errno=RET.NODATA, errmsg="用户或密码错误")

    session['name'] = user.name
    session['user_id'] = user.id
    session['mobile'] = user.mobile

    return jsonify(errno=RET.OK, errmsg="OK")


@api.route('/session', methods=["GET"])
def check_login():
    name = session.get('name')
    if name is not None:
        return jsonify(errno=RET.OK, errmsg='true', data={"name": name})
    else:
        return jsonify(errno=RET.SESSIONERR, errmsg="false")


@api.route('/session', methods=['DELETE'])
def checkout():
    # 防止csrf_token缺失
    csrf_token = session.get('csrf_token')
    session.clear()
    session['csrf_token'] = csrf_token

    return jsonify(errno=RET.OK, errmsg="OK")


